package me.flyray.bsin.server.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import me.flyray.bsin.constants.ResponseCode;
import me.flyray.bsin.context.BsinServiceContext;
import me.flyray.bsin.context.LoginInfoContextHelper;
import me.flyray.bsin.domain.LoginUser;
import me.flyray.bsin.exception.BusinessException;
import me.flyray.bsin.facade.response.AppResp;
import me.flyray.bsin.facade.service.AppService;
import me.flyray.bsin.server.biz.AppBiz;
import me.flyray.bsin.server.domain.SysApp;
import me.flyray.bsin.server.domain.SysAppFunction;
import me.flyray.bsin.server.domain.SysProductApp;
import me.flyray.bsin.server.domain.SysTenant;
import me.flyray.bsin.server.enums.TenantOrgAppType;
import me.flyray.bsin.server.mapper.*;
import me.flyray.bsin.utils.BsinPageUtil;
import me.flyray.bsin.utils.BsinSnowflake;
import me.flyray.bsin.utils.Pagination;
import me.flyray.bsin.utils.RespBodyHandler;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;

public class AppServiceImpl implements AppService {

    @Autowired
    private AppMapper appMapper;
    @Autowired
    private AppFunctionMapper appFunctionMapper;
    @Autowired
    private AppBiz appBiz;
    @Autowired
    private TenantAppMapper tenantAppMapper;
    @Autowired
    private MenuMapper menuMapper;
    @Autowired
    private OrgAppMapper orgAppMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    @Autowired
    private TenantMapper tenantMapper;

    /**
     * 添加应用
     * 1、顶级租户添加默认应用，普通租户添加普通应用
     * @param requestMap
     */
    @Override
    public Map<String, Object> add(Map<String, Object> requestMap) {
        SysApp sysApp = BsinServiceContext.getReqBodyDto(SysApp.class, requestMap);
        String tenantId = (String)requestMap.get("tenantId");
        // 根据租户类型确定应用类型
        SysTenant sysTenant = tenantMapper.selectTenantInfoByTenantId(tenantId);
        if(sysTenant.getType() == 0){
            sysApp.setType(0);
        }else {
            sysApp.setType(1);
        }
        sysApp.setAppId(BsinSnowflake.getId());
        appBiz.savaApp(sysApp,tenantId);
        return RespBodyHandler.setRespBodyDto(sysApp);
    }

    /**
     * 删除(解绑)应用
     * 1、判断当前租户下该应用是授权应用，还是新增应用，授权应用不能删除
     * 2、判断该应用是否被授权其他机构
     * 3、解除租户与应用的绑定
     * 4、解除菜单与角色绑定关系
     * 5、删除应用下的角色
     * 6、删除应用下的菜单
     * 7、删除应用
     * @param requestMap
     */
    @Override
    public Map<String, Object> delete(Map<String, Object> requestMap) {
        SysApp sysApp = BsinServiceContext.getReqBodyDto(SysApp.class, requestMap);
        LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
        String tenantId = loginUser.getTenantId();
        String appId = sysApp.getAppId();
        // 授权应用不能删除
        String type = tenantAppMapper.selectTenantAppType(tenantId, appId).toString();
        if(type.equals(TenantOrgAppType.AUTH.getCode()) || type.equals(TenantOrgAppType.DEF_AUTH.getCode())){
            throw new BusinessException(ResponseCode.APP_NOT_DELETE);
        }
        // 判断该应用是否被授权给其他机构
        List<String> orgList= orgAppMapper.getOrgIdsByAppId(appId);
        if(orgList.size()>0){
            throw  new BusinessException(ResponseCode.APP_EXIST_USER);
        }
        // 解除租户与应用的绑定
        tenantAppMapper.unAuthorizeApp(tenantId, appId);
        // 解除菜单与角色绑定关系
        roleMenuMapper.unAuthorizeMenusByAppId(appId);
        // 删除应用下的角色
        roleMapper.deleteByAppId(appId);
        // 删除应用下的菜单
        menuMapper.deleteByAppId(appId);
        // 删除应用
        appMapper.deleteById(appId);

        return RespBodyHandler.setRespBodyDto(sysApp);
    }

    /**
     * 编辑应用
     * 1、授权应用不能编辑
     * @param requestMap
     */
    @Override
    public Map<String, Object> edit(Map<String, Object> requestMap) {
        SysApp sysApp = BsinServiceContext.getReqBodyDto(SysApp.class, requestMap);
        LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
        String tenantId = loginUser.getTenantId();
        String appId = sysApp.getAppId();
        // 授权应用不能编辑
        String type = tenantAppMapper.selectTenantAppType(tenantId, appId).toString();
        if(type.equals(TenantOrgAppType.AUTH.getCode())){
            throw new BusinessException(ResponseCode.APP_NOT_UPDATE);
        }
        //判断应用编码是否已存在
        SysApp appInfo = appMapper.getAppInfoByAppCode(sysApp.getAppCode());
        if(appInfo != null && !appInfo.getAppId().equals(appId)){
            throw new BusinessException(ResponseCode.APP_CODE_EXISTS);
        }
        appMapper.updateById(sysApp);
        return RespBodyHandler.setRespBodyDto(sysApp);
    }

    /**
     * 根据当前租户多条件分页查询应用
     * @param requestMap
     * @return
     */
    @Override
    public Map<String,Object> getPageList (Map<String, Object> requestMap) {
        LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
        String tenantId = loginUser.getTenantId();
        String appId = (String)requestMap.get("appId");
        String appCode = (String)requestMap.get("appCode");
        String appName = (String)requestMap.get("appName");
        Pagination pagination = (Pagination) requestMap.get("pagination");
        BsinPageUtil.pageNotNull(pagination);
        PageHelper.startPage(pagination.getPageNum(),pagination.getPageSize());
        List<SysApp> sysApps = appMapper.selectPageList(tenantId,appId,appCode,appName);
        PageInfo<SysApp> pageInfo = new PageInfo<SysApp>(sysApps);
        return RespBodyHandler.setRespPageInfoBodyDto(pageInfo);
    }

    /**
     * 查询当前租户下的可授权的应用
     * @param requestMap
     * @return
     */
    @Override
    public Map<String, Object> getAuthorizableList(Map<String, Object> requestMap) {
        LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
        String tenantId = loginUser.getTenantId();
        String appName = (String)requestMap.get("appName");
        List<SysApp> sysApps = appMapper.selectPublishApps();
       return RespBodyHandler.setRespBodyListDto(sysApps);
    }

    /**
     * 查询某个租户下已授权应用
     * @param requestMap
     * @return
     */
    @Override
    public Map<String, Object> getAuthorizedList(Map<String, Object> requestMap) {
        LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
        String tenantId = (String)requestMap.get("tenantId");
        if(StringUtils.isEmpty(tenantId)){
            tenantId = loginUser.getTenantId();
        }
        if(tenantMapper.selectTenantInfoByTenantId(tenantId).getType() == 0){
            List<AppResp> sysApps = appMapper.selectListByTenantIdAndAppName(tenantId,null);
            return RespBodyHandler.setRespBodyListDto(sysApps);
        }
        List<AppResp> sysApps = appMapper.selectListByTenantId(tenantId);
        return RespBodyHandler.setRespBodyListDto(sysApps);
    }

    /**
     * 查询基座需要注册的所发布子应用
     * @param requestMap
     * @return
     */
    @Override
    public Map<String, Object> getPublishedApps(Map<String, Object> requestMap) {
        List<SysApp> sysApps = appMapper.selectPublishApps();
        return RespBodyHandler.setRespBodyListDto(sysApps);
    }

    @Override
    public Map<String, Object> addAppFunction(Map<String, Object> requestMap) {
        SysAppFunction appFunction = BsinServiceContext.getReqBodyDto(SysAppFunction.class, requestMap);
        appFunction.setAppFunctionId(BsinSnowflake.getId());
        appFunctionMapper.insert(appFunction);
        return RespBodyHandler.setRespBodyDto(appFunction);
    }

    @Override
        public Map<String, Object> editAppFunction(Map<String, Object> requestMap) {
        SysAppFunction appFunction = BsinServiceContext.getReqBodyDto(SysAppFunction.class, requestMap);
        appFunctionMapper.updateById(appFunction);
        return RespBodyHandler.setRespBodyDto(appFunction);
    }

    @Override
    public Map<String, Object> deleteAppFunction(Map<String, Object> requestMap) {
        String appFunctionId = (String)requestMap.get("appFunctionId");
        appFunctionMapper.deleteById(appFunctionId);
        return RespBodyHandler.RespBodyDto();
    }

    @Override
    public Map<String, Object> getAppFunctionList(Map<String, Object> requestMap) {
        String appId = (String)requestMap.get("appId");
        List<SysAppFunction> sysApps = appFunctionMapper.selectListByAppId(appId);
        return RespBodyHandler.setRespBodyListDto(sysApps);
    }

    @Override
    public Map<String, Object> getAppFunctionPageList(Map<String, Object> requestMap) {
        String appId = (String)requestMap.get("appId");
        Pagination pagination = (Pagination) requestMap.get("pagination");
        BsinPageUtil.pageNotNull(pagination);
        PageHelper.startPage(pagination.getPageNum(),pagination.getPageSize());
        List<SysAppFunction> appFunctionList = appFunctionMapper.selectListByAppId(appId);
        PageInfo<SysAppFunction> pageInfo = new PageInfo<SysAppFunction>(appFunctionList);
        return RespBodyHandler.setRespPageInfoBodyDto(pageInfo);
    }

}
